package org.shop.common.service.base.impl;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.operator.conn.conf.ConfigDbConfig;
import org.operator.entity.orm.MappingAssignment;
import org.operator.jdbc.D;
import org.shop.common.dao.base.IBaseDao;
import org.shop.common.until.AbstractPageResult;
import org.shop.common.until.AjaxPage;
import org.shop.common.until.PageResultListCovertMap;
import org.shop.common.until.TimeConvert;


public abstract class BaseServiceImpl<T> implements IBaseDao<T> {
	
	/**
	 * 参数
	 */
	private Map<String, String> param;
	
	private String splitKey;
	
	private Object objColum;
	
	protected String covertsplitKey;
	
	/**
	 * 数据映射
	 */
	private T objEntityClass ;
	
	// 关联表搜索条件
    protected String associationWhere = "";
	
    /**
     * 时间搜索键
     */
    private String timeGpKey = "timegp";
    
    /**
     * 搜索条件临时属性
     */
    protected  String searchTemporary = "";
    
	public void setAssociationWhere(String associationWhere) {
		this.associationWhere = associationWhere;
	}


	public Object getobjColum() {
		return objColum;
	}


	private String tableName;
	/**
	 * @param param
	 */
	public BaseServiceImpl(Map<String, String> param, String splitKey, T objEntityClass)
	{
		this.param = param;
		
		this.splitKey = splitKey;
		
		String columClassName = this.geColumClassName();
		
//		AutoBuildProperties auto = new AutoBuildColum(columClassName);
//		
//		auto.buildProperties();
//		
//		auto.buildDataReflection();
		
		this.objColum = (new MappingAssignment(columClassName)).reflectionValue(); 
		
		this.setTableName(columClassName);
		
		this.objEntityClass = objEntityClass;
		
	}
	
	
	/**
     * 获取分页数据列表
     * @return array
     */
    public AbstractPageResult<T> getDataList()
    {
        // 店铺搜索条件
        String where = this.getSearchBuildWhere();
        
        if (this.associationWhere != "" ) {
        	where += " and " + this.associationWhere;
        }
        
        if (this.searchTemporary != "") {
        	 where += " and " + this.searchTemporary;
        }
        
        String matchWhere = this.getMatchingSearchBuildWhere();
        
        if(matchWhere != "" && where != "") {
        	where += " and "+matchWhere;
        } else if(where == "" && matchWhere != "") {
        	where += matchWhere;
        }
        
        String timeWhere = "";
        
        if ( this.param != null && null != this.param.get(this.timeGpKey)) {
            
            timeWhere = this.parseTimeWhere();
        }
        
        if ( timeWhere != "" ) {
        	 where += " and " + timeWhere;
        }
       
        AbstractPageResult<T> data = this.getDataByPage(where);

        return data;
    }
	
    
    /**
     * 分页读取数据
     * @return array
     */
    protected AbstractPageResult<T> getDataByPage(String where)
    {
        int pageNumber = this.getPageNumber();
        
        long count = where != "" ? D.M(this.tableName).where(where).count() : D.M(this.tableName).count();
        
        System.out.println(pageNumber);
        
        System.out.println(count);
        
        AjaxPage pageObj = new AjaxPage(count, pageNumber, this.param);
        
        List<T> dataList;
        
        System.out.println(where);
        
        if (where == "") {
        	dataList = D.M(this.objEntityClass).order(this.getSearchOrderKey()).limit(pageObj.getFirstRow(), pageNumber).select();
        } else {
        	dataList = D.M(this.objEntityClass).where(where).order(this.getSearchOrderKey()).limit(pageObj.getFirstRow(), pageNumber).select();
        }
       
        AbstractPageResult<T> result = this.getResult(dataList, pageObj);
    
        return result;
    }
    
    /**
     * 
     * @param dataList
     * @param pageObj
     * @return
     */
    protected  AbstractPageResult<T> getResult(List<T> dataList, AjaxPage pageObj) {
    	 
    	PageResultListCovertMap<T> result = PageResultListCovertMap.getResult(dataList, pageObj);
    	    
        return result;
    }
    
    /**
     * 获取排序
     */
    protected String getSearchOrderKey()
    {
        try {
			return ((String)this.objColum.getClass().getMethod("getId").invoke(this.objColum)) + " DESC ";
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
        
        return null;
    }
    
    /**
     * 获取分页数目
     */
    protected int getPageNumber()
    {
        return Integer.valueOf((ConfigDbConfig.getInstance("system").getConfig().get("page_number")));
    }
    
    /**
     * 获取 分页类
     */
    protected String getPageClass ()
    {
        return ConfigDbConfig.getInstance("system").getConfig().get("page_class");
    }
    
    /**
     * 组装搜索条件（模糊搜索）
     * @return array
     */
    protected String getSearchBuildWhere()
    {
        if( this.param == null ){
            return "";
        }

        String [] likeSearch = this.likeSearchArray();
        
        if( likeSearch.length == 0 ){
            return "";
        }
        
        Map<String, String> data = this.parseDataWhere();

        Map<String, String> mapSearch = this.create(data);

        if( mapSearch.isEmpty() ){
        	
            return "";
        }
        
        StringBuilder str = new StringBuilder(" 1=1 ");
        
        Object value ;
        
        for( int i = 0; i < likeSearch.length; i++){
            
        	value = mapSearch.get(likeSearch[i]);
        	
        	if( value == null ){
                continue;
            }
        	
        	str.append(" and ").append(likeSearch[i]).append(" like ").append(value).append("%");
        }
        
        return str.toString().substring(0, str.length() - 1);
    }
    
    /**
     * 组装搜索条件（匹配搜索）
     * @return array
     */
    protected String getMatchingSearchBuildWhere()
    {
        if( this.param == null ){
            return "";
        }

        String [] search = this.searchArray();
        
        if( search.length == 0 ){
            return "";
        }
        
        Map<String, String> mapSearch = this.create(this.param);

        if( mapSearch.isEmpty() ){
        	
            return "";
        }
        
        StringBuilder str = new StringBuilder(" 1=1 ");
        
        Object value ;
        
        for( int i = 0; i < search.length; i++){
            
        	value = mapSearch.get(search[i]);
        	
        	if( value == null ){
                continue;
            }
        	
        	str.append(" and ").append(search[i]).append(" = ").append(value);
        }
        
        return str.toString();
    }
    
    
    
    
    /**
     * 处理时间 搜索条件
     * @return array
     */
    protected String parseTimeWhere()
    {
        
    	String timeParam = this.param.get(this.timeGpKey);
    	
        if (null == timeParam) {
            return "";
        }
        
        if ( -1 == timeParam.indexOf(" - ")) {
            return "";
        }
        
        String [] time = timeParam.split(" - ");
       
        TimeConvert timeObj = new TimeConvert(time[0]);
        
        String startTime = timeObj.dateToStamp();
        
        timeObj.setTime(time[1]);
        
        String endTime = timeObj.dateToStamp();
        
        return " between " + startTime + " and " + endTime;
    }
    
    /**
     * 获取模糊搜索字段
     * @return
     */
    protected String [] likeSearchArray() {
    	return new String[0];
    }
    
    /**
     * 
     * @return
     */
    protected String [] searchArray() {
    	return new String[0];
    }
    
    /**
     * 获取搜索时间splitKey
     */
    protected String getSearchTimesplitKey()
    {
    	Class<?> cs = this.objColum.getClass();
    	
        try {
			return (String) cs.getMethod("getCreate_time").invoke(this.objColum);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        return "";
    }
    
    /**
     * 回调方法【处理方法】关联字段相互替换
     */
    protected Map<String, String> parseDataWhere()
    {
    	Map<String, String> map = new HashMap <String, String>(this.param);
        
    	map.put(this.covertsplitKey, !map.containsKey(this.splitKey) ? map.get(this.covertsplitKey) : map.get(this.splitKey) );
        
        map.remove(this.splitKey);
        
        return map;
    }
    
    /**
     * 删除不是数据库字段的数据
     * @param param
     * @return
     */
    private Map<String, String> create(Map<String, String> data)
    {
    	String [] field = this.getDbField();
    	
    	//深度复制 不能改变值
    	Map<String, String> map = new HashMap<String, String>(data);
    	
    	Object value;
    	
    	for (int i = 0; i < field.length; i++) {
    		
    		value = map.get(field[i]);
    		
    		if (value == null || value == "") {
    			map.remove(field[i]);
    		}
    	}
    	return map;
    }
    
	protected abstract IBaseDao<T> getMapper();
	
	/**
	 * 获取字段类名
	 * @return
	 */
	protected abstract String geColumClassName();
	
	
	
	/**
	 * 获取查询字段
	 * @return
	 */
	protected String [] getDbField()
	{
		Field [] field = this.objColum.getClass().getDeclaredFields();
		
		int i, j = field.length;
		
		String [] dbFiled = new String [j];
		
		try {
			for (i = 0; i < j; i++) {
				field[i].setAccessible(true);
				
				dbFiled[i] = (String) field[i].get(this.objColum);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return dbFiled;
	}
	
	protected String getSelectField() {
		
		String [] field = this.getDbField();
		
		StringBuilder str = new StringBuilder();
		
		int lastIndex = field.length - 1;
		
		for (int i = 0; i < lastIndex; i++) {
			str.append(field[i]).append(",");
		}
		
		str.append(field[lastIndex]);
		
		return str.toString();
		
	}
	

	public Map<String, String> getParam() {
		return param;
	}


	public void setParam(Map<String, String> param) {
		this.param = param;
	}


	public String getsplitKey() {
		return splitKey;
	}


	public void setsplitKey(String splitKey) {
		this.splitKey = splitKey;
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}
	
}
